package net.jqsoft.common.lang;

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 密码工具
 * 
 * 
 * @author wangjie
 *
 */
public class SecretTools {

	public static final Logger LOGGER = LoggerFactory.getLogger(SecretTools.class);

	public static final String ALG_AES = "AES";
	protected static final String ALG_HMAC_MD5 = "HmacMD5";
	
	/**
	 * 生成HMAC签名
	 *
	 * @param algorithm  算法
	 * @param plaintext  明文
	 * @param appKey 秘钥
	 */
	public static String hmacDigest(String plaintext, String secretKey) {
		try {
			Mac mac = Mac.getInstance(ALG_HMAC_MD5);
			byte[] secretByte = secretKey.getBytes();
			byte[] dataBytes = plaintext.getBytes();
			SecretKey secret = new SecretKeySpec(secretByte, ALG_HMAC_MD5);
			mac.init(secret);
			return byte2HexStr(mac.doFinal(dataBytes));
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}
	
	
	/**
	 * AES加密
	 */
	public static String aesEncrypt(String content, String password) {
		try {
			KeyGenerator kgen = KeyGenerator.getInstance(ALG_AES);
			kgen.init(128, new SecureRandom(password.getBytes()));
			SecretKey secretKey = kgen.generateKey();
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALG_AES);
			Cipher cipher = Cipher.getInstance(ALG_AES);
			byte[] byteContent = content.getBytes(StringTools.UTF8);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			return byte2HexStr(cipher.doFinal(byteContent));
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * AES解密
	 */
	public static String aesDecrypt(String content, String password) {
		try {
			KeyGenerator kgen = KeyGenerator.getInstance("AES");
			kgen.init(128, new SecureRandom(password.getBytes()));
			SecretKey secretKey = kgen.generateKey();
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
			Cipher cipher = Cipher.getInstance("AES");// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
			byte[] result = cipher.doFinal(hexStr2Bytes(content));
			return byte2HexStr(result); // 加密
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
		return null;
	}

	private static String byte2HexStr(byte[] bytes) {
		StringBuilder hs = new StringBuilder();
		String stmp;
		for (int n = 0; bytes != null && n < bytes.length; n++) {
			stmp = Integer.toHexString(bytes[n] & 0XFF);
			if (stmp.length() == 1)
				hs.append('0');
			hs.append(stmp);
		}
		return hs.toString().toUpperCase();
	}

	private static byte[] hexStr2Bytes(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

}